home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 2 / Gold Medal Software Volume 2 (Gold Medal) (1994).iso / database / cff51b.arj / CFF.DOC < prev    next >
Text File  |  1993-10-23  |  58KB  |  1,711 lines

  1.  
  2.                      Culvers Fabulous Filesystem
  3.                             Version 5.1
  4.                             Beta Release
  5.                            October 23, 1993
  6.  
  7.               Copyright 1991, 1992, 1993 Norman D. Culver
  8.                           All Rights Reserved
  9.  
  10.  
  11.                     Send bug reports and suggestions to:
  12.                      70672.1257@COMPUSERVE.COM Internet
  13.                                  or
  14.                             Oxbow Software
  15.                        1323 S.E. 17th Street #662
  16.                         Ft. Lauderdale, FL 33316
  17.                          (305) 527-1663 Phone
  18.                          (305) 760-7584 Fax
  19.  
  20.  
  21.         This software package is distributed as a preliminary version for
  22.                 TESTING PURPOSES ONLY, WITHOUT ANY WARRANTY;
  23.                    without even the implied warranty of
  24.             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  25.  
  26.  
  27. GENERAL DESCRIPTION
  28.  
  29. This distribution contains a single threaded 32 bit portable library
  30. compiled with gcc for the Intel 386 cpu. The library contains external
  31. references to functions in 'cfport.c' which is supplied as source code.
  32. The user can modify cfport.c to accommodate a non-unix like OS.
  33.  
  34. The user API for the library is declared in the file 'cff.h' and described
  35. in this document. CFF is a filesystem/database engine which handles
  36. allocation of memory, extended memory and disk. It supports incrementally
  37. hashed and B+ tree storage maps in an identical fashion for memory and
  38. disk. The standard flavors of malloc are included. NEW for the first time,
  39. to my knowledge, is the ability to malloc by category and the ability
  40. to malloc PERMANENTLY.
  41.  
  42. Data is stored in and accessed through 'objects' which are referenced
  43. in the classical filesystem manner. e.g. MEMORY/myobject/subobject/...
  44. Objects are opened and closed in the time honored unix fashion. But there
  45. is a big difference between CFF objects and normal filesystem objects.
  46. Each object has the properties of a directory, stack, file, index and
  47. repository. Objects can be created as F_SORTED, in which case they are
  48. B+ trees, and/or with their own local 'bitmaps' for locality of reference,
  49. or, if hashed, with PREALLOCATED DATA AND ENTRIES for ultra fast inserts.
  50. The objects expand and shrink automatically as entries are added or deleted.
  51. The in-core index for hashed objects is never saved to disk because it can be
  52. rebuilt when the object is loaded. Data can be accessed directly in the
  53. localizer buffers or copied to/from user space.
  54.  
  55.  
  56. COPY OBJECTS
  57.  
  58. The 'cfcopy' command will move an object and all subobjects within and
  59. between filesystems. A filesystem on disk is denoted with the extension
  60. '.cff'.     The filesystems for memory and extended memory
  61. (if it exists) are predefined as MEMORY and EXTDMEM. The copy command
  62. will create a filesystem on disk if an object is copied to a '.cff' object.
  63.  
  64. The command: 
  65.  
  66.     cfcopy("newsys.cff", "MEMORY/object/subobject/target");
  67.  
  68. copies the object named 'target' to the disk file newsys.cff and thus
  69. 'target' becomes a filesystem. Conversely, filesystems can become objects, etc.
  70.  
  71.  
  72. PATHNAME TRANSLATION
  73.  
  74. A pathname translation facility permits brevity.
  75. Translation dictionaries are maintained for process, application and system.
  76.  
  77. Example:
  78.  
  79. void *h1, *h2;
  80.  
  81.      cfdef("phone book", "myfile.cff/users/applications/faxmodem/phones");
  82.      h1 = cfopen("phone book", F_RDWR, NULL);
  83. or
  84.      h2 = cfcopy("MEMORY/tempobj", "phone book");
  85.      
  86. or
  87.      h2 = cfcopy("MEMORY/tempobj", h1);
  88.  
  89. And when finished you can get a fully garbage collected and shrunk disk object 
  90. with the command:
  91.  
  92.  
  93.     cfcopy(h1, h2);
  94. or
  95.     cfcopy("phone book", h2);
  96. or
  97.     cfcopy("phone book", "MEMORY/tempobj");
  98.  
  99.  
  100. EXTERNAL FILES
  101.  
  102. It is possible to access normal OS files and directories. If a path doesn't
  103. reference a .cff filesystem then it is assumed to be external. Copy to/from an
  104. external file only exercises the file property of an object, so it is
  105. trivial to import/export external data.
  106.  
  107.  
  108. FANCY MALLOCS
  109.  
  110. The CFF library supplies standard versions of malloc, calloc, realloc etc.
  111. which MUST superceed the standard compiler versions. Don't worry, these
  112. implementations are fast and debugged. This BETA version of the library
  113. does not include debugging support for when you corrupt the heap, it will be
  114. in the commercial version when it is released.
  115.  
  116. The enhancements to malloc are simple to use but rather complicated to
  117. implement. They permit the programmer to malloc, calloc, free etc. by
  118. CATEGORY and they are FAST. Category 0 is reserved for normal malloc, and
  119. is somewhat segregated in the address space because it calls 'sbrk()'
  120. directly. All other categories call cfmalloc() which does it's own calls
  121. to sbrk (actually PORTSBRK in cfport.c). NOTE: Normal malloc, etc. will work
  122. even if cfinit() is not issued. This is nice.
  123.  
  124. Examples:
  125.  
  126. void *ptr;
  127.  
  128.     ptr = mallocC (5, 1024);  // malloc 1K bytes for category 5
  129.     freeC (5, ptr);           // free the pointer in category 5
  130.     freecat (5);              // free all memory allocated to category 5
  131.  
  132. Permanent categories have negative numbers.
  133.  
  134.     ptr = malloc (-20, 1024);  // malloc 1K bytes for permanent category -20
  135.     freeC (-20, ptr);          // free the pointer in category -20
  136.     freecat (-20);             // free all memory allocated to category -20
  137.  
  138.  
  139. Permanent categories are enabled only if the programmer has named a
  140. filesystem when 'cfinit' is called.
  141.  
  142. main()
  143. {
  144. cfinit("app1", 512, "myfile.cff"); // enables permanent categories in myfile.cff
  145. or
  146. cfinit("app1", 512, NULL);         // permanent categories are disabled;
  147.  
  148. ...
  149.  
  150. cfexit(); // saves active permanent categories and closes objects
  151. }
  152.  
  153. Data in active permanent categories is reloaded to exactly the same memory
  154. addresses at program startup and saved in the named filesystem at program exit.
  155. Creep in the data segment as program development proceeds is accommodated
  156. by setting the variable 'heapstart' in cfport.c. The programmer should
  157. pick a number large enough to accommodate the environment in which development
  158. is taking place. If C++ is used, static constructors can gobble a lot of
  159. space before cfinit() is called. The command cfcreep() returns the amount
  160. of space in the safety zone. WARNING: you can't change heapstart after
  161. permanent categories have been saved in a file.
  162.  
  163. The named filesystem can hold permanent categories for multiple applications
  164. providing the applications are uniquely identified by the first argument
  165. to cfinit().
  166.  
  167. In a clean design, a programmer would save a small number of pointers (one??)
  168. to a complex memory structure which will come and go automatically as the
  169. application is run. The purpose here is to speed up the process of loading
  170. permanent objects. Some CAD programs take 30 minutes to start; with CFF
  171. startup can be reduced to seconds on similarly endianed machines.
  172.  
  173. for example:
  174.  
  175. main()
  176. {
  177. struct masterstruct *masterptr;
  178.     
  179.     cfinit("myapp", 256,"myfile.cff");  // PERMINFO is now defined
  180.     if(!cfisnew(PERMINFO))
  181.     {/* The file is not new, load the saved copy of masterptr */
  182.         cfget(PERMINFO, "masterptr", 9, &masterptr, sizeof(void *));
  183.     }
  184.     else
  185.     {/* The file is new, build the basic structures */
  186.         masterptr = mallocC(-1, sizeof(masterstruct)); // or whatever
  187.  
  188.         ...  // build memory structures based on masterptr
  189.              // and various negative categories
  190.     }
  191.  
  192.     ...  // use and modify the permanent structures
  193.          // always use negative categories
  194.  
  195.     /* Save the master pointer before exit */
  196.     cfreput(PERMINFO, "masterptr", 9, &masterptr, sizeof(void *));
  197.     cfexit();
  198. }
  199.  
  200. PREDEFINED PATHNAMES (use as the leading element of a path)
  201.  
  202.     MEMORY    the memory filesystem
  203.     EXTDMEM   the extended memory filesystem
  204.  
  205. PREDEFINED PATHNAMES or HANDLES (use as the leading element or as a handle)
  206.  
  207.     PERMFILE  the filesystem which was mentioned in cfinit()
  208.     PERMCAT   an object in PERMFILE containing the app's permanent categories
  209.     PERMINFO  an object in PERMFILE into which the user can store app info
  210.  
  211.  
  212. ALIGNMENT
  213.  
  214. The granularity of the BETA release is 16 bytes for malloc and 32 bytes
  215. for filesystem allocations. I am considering allowing each bitmap to 
  216. carry a different alignment, if all programmers used gcc then I could
  217. use long long arguments in the user API.
  218.  
  219. NODE SIZES
  220.  
  221. Node (bucket) sizes can range from 512 bytes to 8192 bytes. When an
  222. object is created, the default size is 2048 bytes. The programmer can
  223. modify this size by setting a flag in the mode bits for cfopen. The
  224. root directory of a filesystem is defaulted to 1024 bytes per node.
  225.  
  226.         F_FILEONLY      512 bytes
  227.         F_BIGDIR        4096 bytes
  228.         F_HUGEDIR       8192 bytes
  229.         
  230.  
  231. KEYS, ITEMS and DATA
  232.  
  233. Keys are the names of things in the filesystem. When used as part of a 
  234. path the key must contain only characters in the range 0x40 to 0x7f 
  235. (space to tilde) or it will be rejected by the name translation mechanism.
  236. In all other cases a key may contain anything. When using hashed objects
  237. the programmer should make a distinction between long and short keys.
  238. Short keys are 8 bytes or less and are stored directly in the hash buckets
  239. along with Items. Long keys are stored in a special KEYCACHE area and
  240. require the overhead of the hash bucket entry which is 20 bytes plus
  241. the overhead of the KEYCACHE which is 13 bytes + the size of the key.
  242. Note: the minimum KEYCACHE allocation is 32 bytes. When a long key is
  243. stored in a hash bucket the 8 byte key region is converted to an alternative
  244. hash value for the key, this ensures that only one key comparison
  245. is ever done. B+ tree objects store the keys and items together in the
  246. tree nodes. The programmer should ensure that at least 2 keys will fit
  247. into a B+ tree node, 1 key per node results in a B tree.
  248.  
  249. The key comparison routine can be set for each object with the command
  250. cfkeycmp(handle, funcaddr);
  251.  
  252. Items are the basic insertable/retrievable elements in a node. They are
  253. 64 bits in size with the high 4 bits reserved for tags. B+ trees can support
  254. untagged items if created with F_UNTAGGED set.
  255.  
  256. The programmer will find that 64 bit items are a bit of a pain, especially
  257. if his compiler does not support the long long type. They are worth the
  258. extra effort, believe me.
  259.  
  260. When the system stores a tagged item it checks the high 4 bits, if they
  261. are non-zero it assumes that a tag is already present, otherwise the
  262. item is tagged as a STO_VALUE. Be SURE that your program generated items
  263. have the high 4 bits set to zero.
  264.  
  265. Due to the tagged nature of most items, the system can automatically allocate
  266. and deallocate storage if the item happens to describe a chunk of data.
  267. Currently the maximum size of a single contiguous chunk is 16 Megabytes -1.
  268. This can change if I implement adjustable alignment per bitmap.
  269. See the file cff.h for tag values.
  270.  
  271. The item comparison routine can be set for each object with the command
  272. cfitemcmp(handle, funcaddr);
  273.  
  274. A copy of the default keycmp and itemcmp functions are located in the
  275. module cfport.c so that the programmer can see what needs to be done for
  276. alternative functions.
  277.  
  278.  
  279. HASHED vs SORTED
  280.  
  281. The default method for an object is hashed. The root directory of a
  282. filesystem is forced to be hashed even if created as F_SORTED. Thus
  283. a SORTED object cannot become a filesystem with the cfcopy command.
  284. I may change this but it complicates opening a filesystem.
  285.  
  286. SORTED pros
  287. 1. Sequential access of a sorted object produces sorted output.
  288. 2. Sorted objects can support untagged items, no subobjects are allowed.
  289. 3. Normal mode duplicate entries have the overhead of only one key per node.
  290. 4. An unlimited number of normal mode duplicate entries is supported.
  291. 5. There is no in-core index for the nodes. This could be important for
  292.    an object with 100 million items.
  293. 6. Inserts and deletes to sorted objects do not invalidate the mark.
  294.  
  295. SORTED cons
  296. 1. Access and update of sorted objects is MUCH slower than hashed.
  297. 2. Key length is limited by the node size.
  298.  
  299. HASHED pros
  300. 1. Hashed objects are fast to update and access, and VERY fast with short keys.
  301. 2. Key length is unlimited (16 Megabytes).
  302. 3. Hashed objects can be created with PREALLOCATED entries and data. This
  303.    produces complete locality of reference and great speed when creating
  304.    a database.
  305.  
  306. HASHED cons
  307. 1. The in-core index for each object takes up space (4 bytes per bucket).
  308.    This is a consideration when the object contains a lot of items. The
  309.    maximum bucket of 8192 bytes contains 406 items.
  310. 2. Normal mode duplicate entries is limited to 406 dups.
  311. 3. Under pathological conditions the hashed object may fill up, i.e. a
  312.    bucket may contain a mix of keys which cannot be split.
  313. 4. Sequential access to a hashed object produces unsorted output.
  314.  
  315.  
  316.  
  317. DUPLICATE ENTRIES
  318.  
  319. Keys with duplicate entries are supported in two ways: the normal
  320. 'dupnum' way and the 'dupname' way. Dupnames are 48 bit unique names + a 12 bit
  321. unique id. Each object can support and control 4093 dupname sets.
  322. Dupnames can be used as keys or items. Normal dups must be accessed by
  323. a key-item combination or sequentially; the items for each normal 
  324. dup should be different.
  325. DO NOT MIX NORMAL AND DUPNAME DUPLICATES.
  326.  
  327.  
  328. OBJECTS AS FILES
  329.  
  330. Any object is a file, just read and write to it. If you read
  331. before writing, read will return ERROR. When an object is closed
  332. space allocated to the file property is truncated to within 128 bytes
  333. of the filesize, filesize is limited to 2G bytes.
  334.  
  335.  
  336. OBJECTS AS STACKS
  337.  
  338. Any object is a stack, just push and pop items or data. Stacks retain
  339. their data when an object is closed and/or copied, stack depth is unlimited.
  340.  
  341. OBJECTS AS DIRECTORIES
  342.  
  343. Any object is a directory, just create a subobject (subdirectory) with
  344. the cfopen or cfsubopen commands. The directory property can be accessed
  345. with cfopendir, cfreaddir, cfrewinddir, cftelldir, cfseekdir and cfclosedir.
  346.  
  347.  
  348. OBJECTS AS INDEXES
  349.  
  350. Any object is an index, just insert, find and delete keyed items.
  351. To find out what is in an object, issue the command cfprintentries(something).
  352.  
  353. OBJECTS AS REPOSITORIES
  354.  
  355. Any object is a repository, just put and get keyed data chunks 
  356. (max 16Meg per chunk, min 32 bytes per chunk).
  357.  
  358.  
  359. INTERNAL BUFFERING
  360.  
  361. This BETA version supports 512 buffer headers and unlimited data
  362. buffering. The cfinit command includes an argument for the number of 1K blocks
  363. of data buffering allowed. cfinit("app",700,NULL) designates that 700K of 
  364. memory be allocated to buffering.
  365.  
  366. Data chunks can be accessed directly in the buffer region with the command
  367. cflocalize(). The localizer will allow up to half of the defined
  368. data region to be allocated to a single localization request, excess
  369. buffers are flushed. The size of the data region may be increased/decreased
  370. dynamically with the cfmodbufs() command.
  371.  
  372. This localizer does not localize blocks; it localizes chunks which may
  373. be large or small. Most of the time the localizer is working with nodes
  374. and keys so the memory reqirements are not large internally. The file
  375. property is read/written in 8K chunks. If the user creates a huge chunk
  376. then it is up to the user to deal with it.
  377.  
  378. Huge data chunks can be accessed with the command cfopen_chunk() followed
  379. by reads and writes to the returned handle.
  380.  
  381.  
  382. LAZY WRITING
  383.  
  384. The writethrough properties of an object can be set with the commands
  385. cfsetlazy(handle) and cfsetverylazy(handle). The command cfclrlazy(handle)
  386. causes the object and all underlying buffers, including the OS, to be flushed.
  387. The default writethrough property of an object causes it to be up to date
  388. at the user API level. By this I mean that the CFF buffers are written to
  389. the OS buffers. In order to ensure that the OS buffers are flushed, the
  390. programmer should issue cfflush(handle) and cfsync() commands when appropriate.
  391.  
  392.  
  393. BITMAPS
  394.  
  395. The term 'bitmaps' is misleading. CFF uses extent maps which are 512 bytes
  396. in size and contain 49 sorted entries per map. Each bitmap set has an
  397. in-core sorted index. The root directory of each filesystem has a bitmap
  398. set by default. Individual objects can be created with a bitmap which
  399. will control space allocation for the object and it's subobjects. If an
  400. object has a bitmap it can be deleted very quickly, the system merely returns
  401. all the space defined by the maps to the parent maps. Without a bitmap the
  402. deletion of a complex object can take a while. Nevertheless, DO NOT USE
  403. BITMAPS unless you know what you are doing. This is because they lead to
  404. fragmentation in any environment that involves active insertions and deletions.
  405. Preferably you would pre-allocate all the anticipated space to the bitmap
  406. when you create the object, but this usually means that you allocate a lot
  407. more than is really needed. To find out more about bitmaps, issue the command
  408. cfprintbitmaps(something). Hashed objects which have preallocated data and
  409. entries do not return space to the controlling bitmaps when something
  410. is deleted, this is good. To shrink a sparsely populated preallocated hashed 
  411. object, copy it.
  412.  
  413. CFF maintains two caches for each set of bitmaps, the KEYCACHE is used
  414. for storage of hashed keys and tends to segregate long keys from the data,
  415. this is good; the CACHE is used to dispense space for data, and nodes.
  416. Bitmaps are stored in the space that they map; often as the first 512
  417. bytes.
  418.  
  419.  
  420. GARBAGE COLLECTION
  421.  
  422. The system actively returns space to the underlying bitmaps and
  423. also coalesces the bitmaps in a timely manner. The system currently does not
  424. compress an object or filesystem in place, i.e. rearrange the placement
  425. of things so that the end of a bitmap contains a nice chunk of space that
  426. can be returned to it's parent. cfcopy() is the rich man's substitute.
  427.  
  428.  
  429. ERROR REPORTING
  430.  
  431. Version 5.1 has very uninformative error reporting.
  432.  
  433.  
  434. ACCESS CONTROL and SECURITY
  435.  
  436. Version 5.1 has no access control or security.
  437.  
  438.  
  439. FILE AND RECORD LOCKING
  440.  
  441. Version 5.1 has no locks.
  442.  
  443.  
  444. DATA COMPRESSION
  445.  
  446. Version 5.1 has no compression algorithm.
  447.  
  448.  
  449. INFORMATIONAL PRINTING
  450.  
  451. The programmer can set the system print function with the command
  452. cfsetprintfunc(int (*funcptr)(int));
  453.  
  454. The print function prints one character at a time and returns 1 if OK
  455. and -1 if a device error.
  456.  
  457. The default print function calls PORTPRINT in cfport.c which writes
  458. one character to file descriptor 1. Unbuffered printing gets you all
  459. there is to see even when the system aborts.
  460.  
  461. CFF contains a built in printf 'cfprintf' which is reentrant and
  462. prints one character at a time.
  463.  
  464.  
  465. cfprintbitmaps(void *something);
  466. Prints the bitmaps of something (a path or handle) and it's parents.
  467.  
  468.  
  469. cfprintentries(void *something);
  470. Prints the contents of the storage maps of something (a path or handle).
  471.  
  472.  
  473. cfpflags(char *label, void *handle)
  474. Prints the flags for an open object and its parents, 
  475. adds a programmer supplied label string.
  476.  
  477.  
  478.  
  479. THE COMMAND SET
  480.  
  481. NOTATION:
  482. void *something     Denotes a path or handle (use either one). 
  483.                     If a path, the object need not be open.
  484. void *handle        Denotes a handle for an open object or data chunk.
  485.  
  486.  
  487.  
  488. INITIALIZATION AND EXIT
  489.  
  490. void cfinit(
  491.               char *appname,    // the name of the application
  492.               int bufferspace,  // size of buffer area in KB
  493.               char *permfile    // path of file containing permanent objs
  494.            )
  495. Initialize, load permanent malloc categories from permfile,
  496. load application and system string definitions from permfile,
  497. define PERMFILE, PERMCAT and PERMINFO to refer to the appropriate
  498. objects in permfile.
  499.  
  500.  
  501. void cfexit(
  502.             void
  503.            )
  504. Save permanent malloc categories, save current application and system string
  505. definitions, close all open objects.
  506.  
  507.  
  508. OPEN CLOSE READ WRITE etc.
  509.  
  510. typedef struct opninfo {
  511.     long initial_entries;  // if hashed object, preallocates buckets
  512.     unsigned long bitmap_prealloc;  // if object has bitmap, initial space
  513.     long data_prealloc;    // if hashed object, data space per initial entry
  514. } OPNINFO;
  515.  
  516. /* OPEN MODE BITS */
  517.  
  518. #define F_RDONLY    0x0001     // The object is readonly, the parents are rdwr
  519. #define F_WRONLY    0x0002     // I don't think this works
  520. #define F_RDWR      0x0003
  521. #define F_CREAT     0x0004     // create if non-existant
  522. #define F_TEMP      0x0008     // delete on close
  523. #define F_UNIQ      0x0010     // create a unique name and append to path
  524. #define F_EXCL      0x0020     // non shared open
  525. #define F_BITMAP    0x0040     // attach a bitmap
  526. #define F_TRUNC     0x0080     // truncate on open
  527. #define F_APPEND    0x0100     // only append when writing to file
  528. #define F_FILEONLY  0x0400     // 512 byte nodes
  529. #define F_BIGDIR    0x0800     // 4096 byte nodes
  530. #define F_HUGEDIR   0x1000     // 8192 byte nodes
  531. #define F_SORTED    0x8000     // B+ tree
  532. #define F_UNTAGGED  0x10000    // items are untagged if B+ tree
  533. #define F_STAT      0x20000    // The object and parents are readonly
  534.  
  535. void *cfopen(
  536.                 char *path,        // pathname of object
  537.                 long mode,        // open mode bits
  538.                 void *info        // pointer to OPNINFO struct or NULL
  539.             )
  540. Returns an opaque handle or NULL, check errno.
  541.  
  542. void *cfsubopen(
  543.                 void *handle,    // handle of open object
  544.                 void *name,        // name of subobject
  545.                 long mode,        // open mode bits
  546.                 void *info        // pointer to OPNINFO struct or NULL
  547.                )                
  548. Pastes the path, this is a convenience for the programmer.
  549. Returns an opaque handle or NULL, check errno.
  550.  
  551. void *cfopen_chunk(
  552.                    void *handle,    // handle of open object
  553.                    void *item        // pointer to an Item describing a chunk
  554.                   )
  555. Permits read/write access to a fixed length chunk of data.  
  556. Use cfclose() when finished.
  557. Returns an opaque handle or NULL, check errno.
  558.  
  559. void cfclose(
  560.              void *handle
  561.              )
  562. Closes and flushes whatever is referenced by the handle.
  563. If an object or file has been created with F_TEMP, it is deleted on close.
  564.  
  565. void cfflush(
  566.              void *handle
  567.              )
  568. Ensures that all information pertaining
  569. to the object or external file is written out.
  570.  
  571. void cfsync()
  572. Ensures that all information pertaining
  573. to all open objects and external files is written out.
  574.  
  575. long cfread(
  576.             void *handle,
  577.             void *userbuffer,
  578.             long amount
  579.             )
  580. Reads from a file or a chunk.
  581. Returns amount read or ERROR, check errno.
  582.  
  583. long cfwrite(
  584.              void *handle,
  585.              void *userbuffer,
  586.              long amount
  587.             )
  588. Writes to a file or a chunk.
  589. Returns amount written or ERROR, check errno.
  590.  
  591. long cfseek(
  592.             void *handle,
  593.             unsigned long amount,
  594.             int mode
  595.            )
  596. Seeks within a file or a chunk.
  597. It is legal to seek past the end of a file.
  598. CFF Version 5.1 files do not have holes.
  599. Returns position or ERROR
  600.  
  601. /* Seek modes */
  602. #define S_SET 100
  603. #define S_CUR 200
  604. #define S_END 300
  605.  
  606. int cftruncate(
  607.                void *something,
  608.                unsigned long size
  609.               )
  610. Truncates the file property to 'size', returns OK or ERROR
  611.  
  612.  
  613.  
  614. SEQUENTIAL DIRECTORY ACCESS -- JUST LIKE POSIX almost
  615.  
  616. typedef struct cfdirent {
  617.     int d_namlen;
  618.     char *d_name;
  619.     unsigned long d_bytesalloc;
  620.     unsigned long d_bytesused;
  621.     unsigned long d_mode;
  622.     unsigned long d_entrycnt;
  623.     void *d_fpt;
  624. } CFDIRENT;
  625.  
  626. void *cfopendir(
  627.                 void *something,   // path or handle
  628.                 long *mode         // if non NULL, receives mode bits
  629.                )
  630. Opens the directory aspect of a path or handle.
  631. Works for external files.
  632. Returns opaque handle, or NULL, check errno.
  633.  
  634.  
  635. void cfclosedir(
  636.                 void *openhandle
  637.                )
  638. Close using the handle produced by cfopendir.
  639.  
  640.  
  641. CFDIRENT *cfreaddir(
  642.                     void *openhandle
  643.                    )
  644. Returns a pointer to a CFDIRENT struct, or NULL if EOD.
  645.  
  646.  
  647. void cfrewinddir(
  648.                  void *openhandle
  649.                 )
  650. Reset to beginning of directory.
  651.  
  652.  
  653. void cftelldir(
  654.                void *openhandle,
  655.                STOR *curentry
  656.               )
  657. Returns a pointer to the current directory entry.
  658.  
  659.  
  660. void cfseekdir(
  661.                void *openhandle,
  662.                STOR *curentry
  663.               )
  664. Sets the directory search to the spot returned by cftelldir.
  665.  
  666.  
  667. SEQUENTIAL INDEX ACCESS
  668.  
  669. long cfhead(
  670.             void *handle,
  671.             Item *itemptr
  672.            )
  673. Goto beginning of entries, get current item.
  674. Returns OK or ERROR, 
  675.  
  676. long cfhead_dupnum(
  677.                    void *handle
  678.                    void *keyptr,
  679.                    int   keylen,
  680.                    void *itemptr
  681.                   )
  682. Goto beginning of normal duplicate entries for the key, get current item.
  683. Returns OK or ERROR
  684.  
  685. long cfhead_dupname(
  686.                    void *handle
  687.                    void *keyptr,
  688.                    int   keylen,
  689.                    void *itemptr
  690.                   )
  691. Goto beginning of DupName duplicate entries for the key, get current item.
  692. Returns OK or ERROR
  693.  
  694. long cftail(
  695.             void *handle,
  696.             Item *itemptr
  697.            )
  698. Goto end of entries, get current item.
  699. Returns OK or ERROR, 
  700.  
  701. long cftail_dupnum(
  702.                    void *handle
  703.                    void *keyptr,
  704.                    int   keylen,
  705.                    void *itemptr
  706.                   )
  707. Goto end of normal duplicate entries for the key, get current item.
  708. Returns OK or ERROR
  709.  
  710. long cftail_dupname(
  711.                    void *handle
  712.                    void *keyptr,
  713.                    int   keylen,
  714.                    void *itemptr
  715.                   )
  716. Goto end of DupName duplicate entries for the key, get current item.
  717. Returns OK or ERROR
  718.  
  719. long cfnext(
  720.             void *handle,
  721.             Item *itemptr
  722.            )
  723. Goto next sequential entry, get current item.
  724. Returns OK, EOI or ERROR, 
  725.  
  726. long cfnext_dupnum(
  727.                    void *handle
  728.                    void *keyptr,
  729.                    int   keylen,
  730.                    void *itemptr
  731.                   )
  732. Goto next normal duplicate entry for the key, get current item.
  733. Returns OK, EOI or ERROR
  734.  
  735. long cfnext_dupname(
  736.                    void *handle
  737.                    void *keyptr,
  738.                    int   keylen,
  739.                    void *itemptr
  740.                   )
  741. Goto next DupName duplicate entry for the key, get current item.
  742. Returns OK, EOI or ERROR
  743.  
  744. long cfprev(
  745.             void *handle,
  746.             Item *itemptr
  747.            )
  748. Goto previous sequential entry, get current item.
  749. Returns OK, BOI or ERROR, 
  750.  
  751. long cfprev_dupnum(
  752.                    void *handle
  753.                    void *keyptr,
  754.                    int   keylen,
  755.                    void *itemptr
  756.                   )
  757. Goto previous normal duplicate entry for the key, get current item.
  758. Returns OK, BOI or ERROR
  759.  
  760. long cfprev_dupname(
  761.                    void *handle
  762.                    void *keyptr,
  763.                    int   keylen,
  764.                    void *itemptr
  765.                   )
  766. Goto previous DupName duplicate entry for the key, get current item.
  767. Returns OK, BOI or ERROR
  768.  
  769. long cfkey(
  770.            void *handle,
  771.            void *keybufptr,
  772.            int keybuflen
  773.           )
  774. Returns OK, BOI, EOI or ERROR.
  775. If OK, fills the buffer denoted by 'keybufptr' with no more than
  776. 'keybuflen' bytes of the current key.
  777.  
  778. long cfitem(
  779.             void *handle,
  780.             Item *itemptr
  781.            )
  782. Get item from current position.
  783. Returns OK, BOI, EOI or ERROR.
  784.  
  785. long cfdata(
  786.            void *handle,
  787.            void *databufptr,
  788.            int databuflen
  789.           )
  790. Returns OK, BOI, EOI or ERROR if invalid handle or no data available.
  791. If OK, fills the buffer denoted by 'databufptr' with no more than
  792. 'databuflen' bytes of the current key's data area, if it exists.
  793.  
  794.  
  795. long cfkeylen(
  796.               void *handle,
  797.               int *len
  798.              )
  799. returns OK if a current key exists, len is set to the length of the key
  800. NOTE: Short hashed keys always return a length of 8, even if they
  801. were originally shorter.
  802.  
  803.  
  804. long cfdatalen(
  805.                void *handle,
  806.                int *len
  807.               )
  808. returns OK if a current key exists, len is set to data size or 0 if no data
  809.  
  810.  
  811. long cfmark(
  812.             void *handle
  813.            )
  814. Saves the current position. (see cffind_mark()).
  815. Returns OK or ERROR.
  816.  
  817.  
  818. INSERT ITEMS
  819.  
  820. int cfinsert(
  821.               void *handle,
  822.               void *keyptr,
  823.               int   keylen,
  824.               void *itemptr
  825.              )
  826. Returns OK or ERROR, duplicate entries are not allowed
  827.  
  828. int cfreinsert(
  829.               void *handle,
  830.               void *keyptr,
  831.               int   keylen,
  832.               void *itemptr
  833.              )
  834. Returns OK or ERROR, the key must exist, duplicate entries are not allowed.
  835. If the existing item references data, the data space is deleted.
  836.  
  837. int cfinsert_dupnum(
  838.                      void *handle,
  839.                      void *keyptr,
  840.                      int   keylen,
  841.                      void *itemptr,
  842.                      long *dupcnt    // returns the current dupcnt, 1 based
  843.                     )
  844. Returns OK or ERROR, 'normal' duplicates are allowed.
  845.  
  846. int cfreinsert_dupnum(
  847.                      void *handle,
  848.                      void *keyptr,
  849.                      int   keylen,
  850.                      void *itemptr,
  851.                      long *dupnum    // points to the desired dupnum, 0 based
  852.                     )
  853. Returns OK or ERROR, the key and dupnumn'th duplicate must exist.
  854. If the existing item references data, the data space is deleted.
  855.  
  856. NOTE: Items entered as normal duplicates do not remain in the order
  857.       in which they are entered, B+ trees sort the keys and items,
  858.       hashed directories get rearranged when split. Therefore, reinserting
  859.       to a specific dupnum is a chancy business and should be done only
  860.       when the programmer is certain of the algorithm.
  861.  
  862.  
  863. int cfinsert_dupname(
  864.                      void *handle,
  865.                      void *keyptr,
  866.                      int   keylen,
  867.                      void *itemptr,
  868.                      DupName *dupname  // returns current dupname
  869.                      )
  870. Returns OK or ERROR, the value referenced by 'dupname' is filled with the
  871. current DupName.
  872.  
  873. NOTE: DupNames are constantly incremented and provide a completely unique
  874. way to identify a key-item pair. Each DupName contains a 48 bit counter
  875. that is decremented only under special circumstances (see cfdelete_lastdupname).
  876. If a program inserted 1000 dupnames per second, it would take more than 8000 
  877. years to overflow the counter.
  878.  
  879.  
  880.  
  881.  
  882.  
  883. int cfreinsert_dupname(
  884.                      void *handle,
  885.                      void *keyptr,
  886.                      int   keylen,
  887.                      void *itemptr,
  888.                      DupName *dupname    // points to the desired DupName
  889.                      )
  890. If the existing item references data, the data space is deleted.
  891. Returns OK or ERROR, the key and dupname'th duplicate must exist.
  892.  
  893.  
  894. INSERT DATA
  895.  
  896. NOTE: 1. Data may not be inserted in objects with untagged items.
  897.       2. reput acts like realloc, if the entry doesn't exist it is created.
  898.          If dupnums or DupNames are used with reput, then the desired entry
  899.          must exist or the operation fails.
  900.  
  901. void *cfput(
  902.             void *handle,
  903.             void *keyptr,
  904.             int   keylen,
  905.             void *databuffer,
  906.             long  databuflen,
  907.             void *itemptr    // if non NULL then the Item is filled in
  908.            )
  909. Returns 'itemptr' if successful, NULL if not.
  910. The Item referenced by 'itemptr' describes a data chunk.
  911. If itemptr is NULL, then the non-NULL value returned on success is not
  912. a valid itemptr in its own right.
  913.  
  914.  
  915. void *cfreput(
  916.             void *handle,
  917.             void *keyptr,
  918.             int   keylen,
  919.             void *databuffer,
  920.             long  databuflen,
  921.             void *itemptr     // if non NULL then the Item is filled in
  922.            )
  923. Overwrites old data, if no old data, a new entry is created.
  924. Returns 'itemptr' if successful, NULL if not.
  925. The Item referenced by 'itemptr' describes a data chunk.
  926. If itemptr is NULL, then the non-NULL value returned on success is not
  927. a valid itemptr in its own right.
  928.  
  929.  
  930. void *cfput_dupnum(
  931.                    void *handle,
  932.                    void *keyptr,
  933.                    int   keylen,
  934.                    void *databuffer,
  935.                    long  databuflen,
  936.                    void *itemptr,
  937.                    long *dupcnt      // returns the current dupcnt, 1 based
  938.                   )
  939. Returns 'itemptr' if successful, NULL if not.
  940. The Item referenced by 'itemptr' describes a data chunk.
  941. If itemptr is NULL, then the non-NULL value returned on success is not
  942. a valid itemptr in its own right.
  943.  
  944.  
  945. void *cfreput_dupnum(
  946.                    void *handle,
  947.                    void *keyptr,
  948.                    int   keylen,
  949.                    void *databuffer,
  950.                    long  databuflen,
  951.                    void *itemptr,    // if non NULL then the Item is filled in
  952.                    long *dupnum      // references the desired dupnum, 0 based
  953.                   )
  954. Overwrites old data, if no old data, the operation fails.
  955. Returns 'itemptr' if successful, NULL if not.
  956. The Item referenced by 'itemptr' describes a data chunk.
  957. If itemptr is NULL, then the non-NULL value returned on success is not
  958. a valid itemptr in its own right.
  959.  
  960.  
  961. void *cfput_dupname(
  962.                    void *handle,
  963.                    void *keyptr,
  964.                    int   keylen,
  965.                    void *databuffer,
  966.                    long  databuflen,
  967.                    void *itemptr,    // if non NULL then the Item is filled in
  968.                    DupName *dupname  // returns the current DupName
  969.                   )
  970. Returns 'itemptr' if successful, NULL if not.
  971. The Item referenced by 'itemptr' describes a data chunk.
  972. If itemptr is NULL, then the non-NULL value returned on success is not
  973. a valid itemptr in its own right.
  974.  
  975.  
  976. void *cfreput_dupname(
  977.                    void *handle,
  978.                    void *keyptr,
  979.                    int   keylen,
  980.                    void *databuffer,
  981.                    long  databuflen,
  982.                    void *itemptr,      // if non NULL the Item is filled in
  983.                    DupName *dupname    // references the desired DupName
  984.                   )
  985. Overwrites old data, if no old data, the operation fails.
  986. Returns 'itemptr' if successful, NULL if not.
  987. The Item referenced by 'itemptr' describes a data chunk.
  988. If itemptr is NULL, then the non-NULL value returned on success is not
  989. a valid itemptr in its own right.
  990.  
  991.  
  992. RETRIEVE DATA
  993.  
  994. long cfget(
  995.            void *handle,
  996.            void *keyptr,
  997.            void  keylen,
  998.            void *databufptr,
  999.            long  databuflen
  1000.           )
  1001. Read the data for the first item of the key into the buffer for no 
  1002. more than 'databuflen' bytes;
  1003. Returns FOUND, FOUND+1 if dups present, NOTFOUND, or ERROR
  1004. if >= FOUND sets up for sequential access.
  1005.  
  1006. long cfget_dupnum(
  1007.                   void *handle,
  1008.                   void *keyptr,
  1009.                   int   keylen,
  1010.                   void *databufptr,
  1011.                   long  databuflen,
  1012.                   long *dupnum      // references the desired dupnum, 0 based
  1013.                  )
  1014. Read the data for the dupnum'th item of the key into the buffer for no 
  1015. more than 'databuflen' bytes;
  1016. Returns FOUND, FOUND+1, NOTFOUND or ERROR. 
  1017. If >= FOUND, sets up for sequential access.
  1018.  
  1019.  
  1020. long cfget_dupname(
  1021.                   void *handle,
  1022.                   DupName *dupname,  // points to the desired DupName
  1023.                   void *databufptr,
  1024.                   long  databuflen
  1025.                  )
  1026. Read the data for the dupname into the buffer for no 
  1027. more than 'databuflen' bytes;
  1028. Returns FOUND, NOTFOUND or ERROR.
  1029. If FOUND, sets up for sequential access.
  1030.  
  1031.  
  1032. FIND ITEMS
  1033.  
  1034. int cffind(
  1035.            void *handle,
  1036.            void *keyptr,
  1037.            int   keylen,
  1038.            void *itemptr   // if FOUND the item is returned
  1039.           )
  1040. Locates the first item of a key, and sets up for sequential access.
  1041. Returns FOUND, FOUND+1 if dups present, NOTFOUND, or ERROR
  1042.  
  1043.  
  1044. int cffind_dupnum(
  1045.                   void *handle,
  1046.                   void *keyptr,
  1047.                   int   keylen,
  1048.                   void *itemptr,    // if FOUND the item is returned
  1049.                   long *dupnum      // points to the desired dupnum, 0 based
  1050.                  )
  1051. Returns FOUND, FOUND+1, NOTFOUND or ERROR. 
  1052. If >=  FOUND, sets up for sequential access.
  1053.  
  1054.  
  1055. int cffind_dupname(
  1056.                   void *handle,
  1057.                   DupName *dupname  // points to the desired dupname
  1058.                   void *itemptr,    // if FOUND the item is returned
  1059.                  )
  1060. Returns FOUND, NOTFOUND or ERROR. If FOUND, sets up for sequential access.
  1061.  
  1062.  
  1063. int cffind_item(
  1064.                 void *handle,
  1065.                 void *keyptr,
  1066.                 int   keylen,
  1067.                 void *itemptr
  1068.                )
  1069. Locates a key-item pair.
  1070. Returns FOUND, NOTFOUND or ERROR. If FOUND, sets up for sequential access.
  1071.  
  1072.  
  1073. int cffind_mark(
  1074.                 void *handle,
  1075.                 void *itemptr
  1076.                )
  1077. Returns the item for the current mark if the mark is valid (see cfmark()).
  1078. The mark can be invalidated if items are inserted or deleted after the
  1079. mark is set. This phenomenon happens more often with hashed directories
  1080. than with B+ trees.
  1081.  
  1082. Returns FOUND, NOTFOUND or ERROR. If FOUND, sets up for sequential access.
  1083.  
  1084.  
  1085.  
  1086. DELETE ITEMS
  1087.  
  1088. int cfdelete(
  1089.               void *handle,
  1090.               void *keyptr,
  1091.               int   keylen
  1092.              )
  1093. The first item of the key is deleted along with any data.
  1094. Returns OK or ERRORNUM a negative number.
  1095.  
  1096.  
  1097. int cfdelete_item(
  1098.                   void *handle,
  1099.                   void *keyptr,
  1100.                   int   keylen,
  1101.                   void *itemptr
  1102.                  )
  1103. If the key-item pair exists it is deleted along with any data.
  1104. Returns OK or ERRORNUM a negative number.
  1105.  
  1106.  
  1107. int cfdelete_dupnum(
  1108.                     void *handle,
  1109.                     void *keyptr,
  1110.                     int   keylen,
  1111.                     long  dupnum      // 0 based
  1112.                    )
  1113. If the dupnum'th item for the key exists it is deleted along with any data.
  1114. Returns OK or ERRORNUM a negative number
  1115.  
  1116.  
  1117. int cfdelete_dupname(
  1118.                      void *handle,
  1119.                      void *keyptr,
  1120.                      int   keylen,
  1121.                      DupName *dupname
  1122.                     )
  1123. If the dupname exists, it is deleted along with any data.
  1124. If the dupname is deleted, the 'holes' counter is incremented by one.
  1125. Each DupName set contains a 48 bit holes counter. (see cfcountdups()).
  1126. returns OK or ERRORNUM a negative number.
  1127.  
  1128.  
  1129. int cfdelete_lastdupname(
  1130.                          void *handle,
  1131.                          void *keyptr,
  1132.                          int   keylen
  1133.                         )
  1134. If the last DupName for the key exists, it is deleted along with any data.
  1135. The DupName counter is decremented by one.
  1136. Returns OK or ERRORNUM a negative number.
  1137.  
  1138.  
  1139. int cfdelete_lastdupnum(
  1140.                          void *handle,
  1141.                          void *keyptr,
  1142.                          int   keylen
  1143.                         )
  1144. If the last dupnum for the key exists, it is deleted along with any data.
  1145. WARNING: The last dupnum is probably not the last dup entered. B+ trees
  1146. sort all input and hashed directories are reorganized when split/coalesced.
  1147. Returns OK or ERRORNUM a negative number.
  1148.  
  1149.  
  1150. int cfdelete_alldupnames(
  1151.                          void *handle,
  1152.                          void *keyptr,
  1153.                          int   keylen
  1154.                         )
  1155. All 'DupName' entries for the key are deleted along with any data.
  1156. Returns OK or ERROR
  1157.  
  1158.  
  1159. int cfdelete_alldupnums(
  1160.                          void *handle,
  1161.                          void *keyptr,
  1162.                          int   keylen
  1163.                         )
  1164. All 'dupnum' entries for the key are deleted along with any data.
  1165. Returns OK or ERROR
  1166.  
  1167. DELETE OBJECTS 
  1168.  
  1169. int cfunlink(
  1170.               void *something, // path or object handle
  1171.               ...              // optional 2'nd arg if arg 1 is a handle
  1172.             )
  1173.  
  1174. Deletes the object denoted by 'something' and an optional second argument.
  1175. If 'something' is a path, then the target of the path is deleted.
  1176. if 'something' is a handle, then if the second argument is NULL
  1177. the object denoted by the handle is deleted. A non-NULL second argument
  1178. must be a character string which names an entry in the object's index.
  1179. The second argument must not refer to a sub_object.
  1180.  
  1181. Returns OK or ERROR if multiply opened or sub_objects open or not found.
  1182.  
  1183. NOTE: When an object is unlinked all of it's sub-objects are unlinked
  1184. and all data is returned to parent bitmaps. External files can be unlinked.
  1185.  
  1186.  
  1187. STACK OPERATIONS
  1188.  
  1189. long cfpush_item(
  1190.                  void *handle,    // an open object
  1191.                  void *itemptr
  1192.                 )
  1193. Push the item on the objects stack.
  1194. Returns current stack depth or ERROR.
  1195.  
  1196.  
  1197. long cfpush_data(
  1198.                  void *handle,  // an open object
  1199.                  void *datbufptr,
  1200.                  int   datbuflen
  1201.                 )
  1202. Pushes data onto the objects stack (max 16MB). 
  1203. Returns current stack depth or ERROR.
  1204.  
  1205.  
  1206. long cfpop_item(
  1207.                 void *handle,  // an open object
  1208.                 void *itemptr
  1209.                )
  1210. Pops an item from the top of the objects stack.
  1211. IF THE ITEM DESCRIBES DATA, THE DATA HAS NOT BEEN DELETED (use cfretspace()).
  1212. I have chosen this dangerous method of dealing with the stack because
  1213. it can be very useful. i.e. One part of a program can push a lot of data
  1214. without regard for where it is going or assigning a key to it, another
  1215. part of a program can pop the items which describe the data and save the
  1216. items for later keyed retrieval, the data moves once. This method is doubly
  1217. dangerous: First, the programmer must ensure that the data can eventually
  1218. be deleted and Second, if a hashed object contains PREALLOCATED ENTRIES
  1219. then the data should NEVER be deleted because the preallocation mechanism
  1220. will want to reuse the space, and indeed will overwrite the data at some
  1221. time in the future.
  1222. Returns current stack depth or ERROR.
  1223.  
  1224.  
  1225. long cfpop_data(
  1226.                 void *handle,  // an open object
  1227.                 void *datbufptr,
  1228.                 int   datbuflen
  1229.                )
  1230. Pops data (if it exists) from the top of the stack.
  1231. If the top of the stack contains an item that does not describe data
  1232. the item is lost.
  1233. Returns current stack depth or ERROR.
  1234.  
  1235.  
  1236. long cfstackdepth(
  1237.                   void *handle  // an open object
  1238.                  )
  1239. Returns current stack depth or ERROR.
  1240.  
  1241.  
  1242.  
  1243. SPACE ALLOCATION
  1244.  
  1245. void *cfgetspace(
  1246.                   void *handle,  // an open object
  1247.                   long  amount,  // max 16MB
  1248.                   void *itemptr     // receives an Item which describes the space
  1249.                 )
  1250. Returns 'itemptr' if success or NULL.
  1251.  
  1252.  
  1253. int cfretspace(
  1254.                 void *handle,  // an open object
  1255.                 void *itemptr  // pointer to an Item which describes space
  1256.               )
  1257. Returns OK or ERROR
  1258. CFF Version 5.1 will abort if the Item does not describe valid space.
  1259. I think that this is better than returning an error.
  1260.  
  1261.  
  1262.     MEMORY FUNCTIONS
  1263.     void *malloc(size_t)
  1264.     void *calloc(unsigned, unsigned)
  1265.     void *realloc(void *, unsigned)
  1266.     void *valloc(unsigned)
  1267.     void *memalign(unsigned, unsigned)
  1268.     void free(void *)
  1269.     unsigned mallocsize(void *)
  1270.     void *cfmalloc(unsigned, Item *)
  1271.     void cffree(Item *)
  1272.  
  1273.     MEMORY BY CATEGORY FUNCTIONS
  1274.     void *mallocC(long, unsigned)
  1275.     void *callocC(long, unsigned, unsigned)
  1276.     void *reallocC(long, unsigned, unsigned)
  1277.     void *vallocC(long, unsigned)
  1278.     void *memalignC(long, unsigned, unsigned)
  1279.     void freeC(long, void *)
  1280.     void freecat(long)
  1281.  
  1282. CONTROL FUNCTIONS
  1283.  
  1284. long cfmodbufs(
  1285.                 long increment   // positive or negative increment in K bytes
  1286.               )
  1287. Changes the allowed buffering space by 'increment'.
  1288. Returns OK
  1289.  
  1290. long cfsetlazy(
  1291.                void *handle        // an open object
  1292.               )
  1293. Changes the writethrough characteristic of the object to LAZY.
  1294. Some bookeeping entries are forced out.
  1295. Returns OK or ERROR
  1296.  
  1297. long cfsetverylazy(
  1298.                    void *handle  // an open object
  1299.                   )
  1300. Changes the writethrough characteristic of the object to VERYLAZY.
  1301. No data is forced out.
  1302. Returns OK or ERROR
  1303.  
  1304. long cfclrlazy(
  1305.                void *handle   // an open object
  1306.               )
  1307. Sets the writethrough characteristic of the object to NORMAL.
  1308. Forces out everything.
  1309. Returns OK or ERROR
  1310.  
  1311. long cfsetkeycmp(
  1312.                  void *handle,                          // open object
  1313.                  int (*func)(void *, int, void *, int)  // function pointer
  1314.                 )
  1315. Changes the default key comparison routine for an object to a programmer
  1316. supplied version.
  1317. Returns OK or ERROR
  1318.  
  1319. long cfsetitemcmp(
  1320.                  void *handle,                // open object
  1321.                  int (*func)(void *, void *)  // function pointer
  1322.                 )
  1323. Changes the default item comparison routine for an object to a programmer
  1324. supplied version.
  1325. Returns OK or ERROR
  1326.  
  1327. long cfsetprintfunc(
  1328.                  int (*func)(int)  // function pointer
  1329.                 )
  1330. Changes the default system print function to a programmer supplied version.
  1331. The function must print one character at a time,
  1332. and return 1 for success, -1 for error.
  1333. Returns OK
  1334.  
  1335. void cfport_settestflags(
  1336.                          int flags
  1337.                         )
  1338. Set flags in the portability module 'cfport.c'. This command is issued
  1339. before cfinit(). The only defined flag is 1, which causes the extended
  1340. memory driver to enable a 4Meg local buffer for testing purposes.
  1341. If the 1 flag is not set, the system will map extended memory to
  1342. primary memory unless the programmer has included a 'real' extended
  1343. memory driver in cfport.c
  1344.  
  1345.  
  1346. COPY OBJECTS, FILESYSTEMS and FILES
  1347.  
  1348. void *cfcopy(
  1349.              void *something_dst,  // designates the destination
  1350.              void *something_src   // designates the source
  1351.             )
  1352.  
  1353. Copy the source to the destination.
  1354. The arguments can be paths or handles.
  1355. The source may be an object, a filesystem or an external file.
  1356. Ditto for the destination.
  1357. Sorted objects (created with F_SORTED) may not be copied to a filesystem.
  1358. If the source or destination is an external file, then the file property
  1359. of the object is copied.
  1360.  
  1361. Returns a handle to the OPENED destination or NULL.
  1362. NOTE: If the destination argument was an open handle, then the returned
  1363. handle SUPERCEEDS the original. i.e. the open object was deleted and
  1364. recreated.
  1365.  
  1366.  
  1367. DIRECT ACCESS TO DATA IN THE BUFFERS
  1368.  
  1369. void *cflocalize(
  1370.                  void *handle,   // an open object
  1371.                  void *item      // pointer to an Item which describes space
  1372.                 )
  1373. Returns a pointer to memory or NULL.
  1374. This command ties up one buffer header.
  1375. Be certain to release the buffer when finished.
  1376. The buffers are in the heap and thus are not memory protected.
  1377.  
  1378.  
  1379. void cfrelease(
  1380.                void *memptr,  // a pointer to memory returned by cflocalize()
  1381.                long  relmode  // R_CLEAN, R_DIRTY, R_FLUSH
  1382.               )
  1383. Release a buffer. 
  1384. If the release mode is R_CLEAN, then the buffer may never be written out.
  1385. If the release mode is R_DIRTY, then the buffer will eventually be written out.
  1386. If the release mode is R_FLUSH, then the buffer is written out immediately if
  1387. the object writethrough condition is not VERYLAZY. If the object may be in
  1388. VERYLAZY mode, be sure to use (R_DIRTY|R_FLUSH).
  1389.  
  1390.  
  1391. NAME TRANSLATION FUNCTIONS
  1392.  
  1393. int cfdef(
  1394.           char *keyptr,  // the key for the definition string
  1395.           char *defptr  // the definition string, entered in local dictionary
  1396.          )
  1397. Enters the definition string in the local dictionary, under the key.
  1398. Local definitions override application and system definitions.
  1399. Returns OK or ERROR
  1400.  
  1401.  
  1402. int cfundef(
  1403.             char *keyptr   // the key to a definition string
  1404.            )
  1405. Deletes a definition string from the local dictionary.
  1406. returns OK or ERROR
  1407.  
  1408.  
  1409. int cfsysdef(
  1410.               char *keyptr,  // the key for the definition string
  1411.               char *defptr  // the definition string, entered in PERMFILE
  1412.              )
  1413. Enters the definition string in the permanent system dictionary (if it exists).
  1414. PERMFILE is enabled if arg 3 of cfinit() mentions a valid '.cff' file.
  1415. Returns OK or ERROR
  1416.  
  1417.  
  1418. int cfsysundef(
  1419.                char *keyptr  // the key to a defined string
  1420.                )
  1421. Deletes a definition string from the permanent system dictionary.
  1422. Returns OK or ERROR
  1423.  
  1424. int cfappdef(
  1425.               char *keyptr,  // the key for the definition string
  1426.               char *defptr  // the definition string, entered in PERMINFO
  1427.              )
  1428. Enters the definition string in the permanent application dictionary.
  1429. Application definitions override system definitions.
  1430. PERMINFO is enabled if arg 3 of cfinit() mentions a valid '.cff' file.
  1431. Returns OK or ERROR
  1432.  
  1433.  
  1434. int cfappundef(
  1435.                char *keyptr  // the key to a defined string
  1436.                )
  1437. Deletes a definition string from the permanent application dictionary.
  1438. Returns OK or ERROR
  1439.  
  1440.  
  1441. int cftrn(
  1442.           char *input_string,
  1443.           char **output_string
  1444.          )
  1445. Translates the input string to the output string using the dictionaries.
  1446. The programmer must free the output string.
  1447. Returns OK or ERROR
  1448.  
  1449.  
  1450. int cfpathtrn(
  1451.               char *input_string,
  1452.               char **output_string
  1453.              )
  1454. Translates the input string to a fully qualified path, using the dictionaries
  1455. and the current working directory.
  1456. The programmer must free the output string.
  1457. Returns 0 if internal object, 1 if external file, 2 if filesys, 3 if rawdevice
  1458. Returns ERROR if trouble.
  1459.  
  1460.  
  1461. int cfchdir(
  1462.             char *newpath
  1463.            )
  1464. Change the current working directory.
  1465. Returns OK or ERROR
  1466.  
  1467.  
  1468. NOTE: to get the current working directory:
  1469. {
  1470. char *cwd;
  1471.     cfpathtrn(".", &cwd);
  1472.     
  1473.     ...
  1474.     
  1475.    free(cwd);
  1476. }
  1477. NOTE: CFF does not include disk drive prefixes in the cwd, the programmer
  1478.       may include them when opening a file or filesystem.
  1479.  
  1480. NOTE: The translator works mostly on the left hand side of a path;
  1481.       it first tries to translate the whole input string, then it expands
  1482.       the left hand side up to 10 times, then it tries to translate the
  1483.       whole result string. Would a macro facility be helpful?
  1484.  
  1485.  
  1486.  
  1487. INFORMATIONAL FUNCTIONS
  1488.  
  1489. int cflastdupname(
  1490.                   void *handle,
  1491.                   void *keyptr,
  1492.                   int   keylen,
  1493.                   DupName *dupname  // filled if successful
  1494.                  )
  1495. If DupNames exist for the key, 'dupname' is filled with the last one.
  1496. Returns OK or ERROR
  1497.  
  1498. long cfcountdups(
  1499.                  void *handle,
  1500.                  void *keyptr,
  1501.                  int   keylen
  1502.                 )
  1503. Returns the actual duplicate count for a key. If DupNames are being used
  1504. then the actual count is the last DupName minus the number of prior deletions.
  1505. Each DupName key has a deletion counter which is incremented for every
  1506. successful delete except cfdelete_lastdupname().
  1507. Normal duplicates are just overtly scanned and counted.
  1508.  
  1509. int cfstat(
  1510.            void *something, // a handle or a path
  1511.            void *stbuf      // pointer to a CFSTAT struct
  1512.           )
  1513. returns OK or ERROR
  1514.  
  1515. typedef struct cffstat {
  1516.         unsigned long   st_smhead;
  1517.         unsigned long   st_smtail;
  1518.         unsigned short  st_id;
  1519.         unsigned short  st_keysize;
  1520.  
  1521.         STOR           st_dups;
  1522.         unsigned long  st_bmhead;
  1523.         unsigned long  st_bmtail;
  1524.         unsigned long  st_mode;
  1525.         short          st_uid;
  1526.         short          st_gid;
  1527.         long           st_mtime;
  1528.         long           st_ctime;
  1529.  
  1530.         unsigned long  st_highleaf;
  1531.         unsigned long  st_size;
  1532.         unsigned long  st_alloc;
  1533.         unsigned long  st_entrycnt;
  1534.         short          st_mapsize;
  1535.         unsigned short st_dupids;
  1536.  
  1537.         long           st_atime;
  1538.         long           st_filesize;
  1539.         long           st_filealloc;
  1540.         long           st_obtype;
  1541.         unsigned int   st_filedups;
  1542.         long           st_ino;
  1543.         short          st_blksize;
  1544.         short          st_dev;
  1545.         short          st_nlink;
  1546.         short          st_rdev;
  1547. } CFSTAT;
  1548.  
  1549.  
  1550.  
  1551.  
  1552.  
  1553. /* MODE BITS in st_mode */
  1554. #define M_ROOTDIR   0x80000000
  1555. #define M_FILEONLY  0x40000000
  1556. #define M_HASHDIR   0x20000000
  1557. #define M_TREEDIR   0x10000000
  1558. #define M_UNTAGGED  0x08000000
  1559. #define M_BITMAP    0x04000000
  1560. #define M_EXTRNFILE 0x02000000
  1561. #define M_PREALLOC  0x01000000
  1562. #define M_IFMT      0x000F0000
  1563. #define M_IFDIR     0x00004000
  1564. #define M_IFIFO     0x00002000
  1565. #define M_IFCHR     0x00001000
  1566. #define M_IFBLK     0x00003000
  1567. #define M_IFREG     0x00008000
  1568. #define M_IREAD     0x00000100
  1569. #define M_IWRITE    0x00000080
  1570. #define M_IEXEC     0x00000040
  1571.  
  1572.  
  1573. long cfentrycnt(
  1574.                 void *something
  1575.                )
  1576. returns the entrycount of a handle or a path, or ERROR
  1577.  
  1578.  
  1579. long cfdepth(
  1580.              void *handle
  1581.             )
  1582. returns treedepth or ERROR
  1583.  
  1584.  
  1585. long cfbytesused(
  1586.                  void *handle
  1587.                 )
  1588. returns the bytes used in the object or ERROR
  1589.  
  1590.  
  1591. long cfbytesalloc(
  1592.                   void *handle
  1593.                  )
  1594. returns the bytes allocated to the object or ERROR
  1595.  
  1596.  
  1597. long cftotalloc(
  1598.                 void *something,
  1599.                 unsigned long *used,
  1600.                 unsigned long *alloc
  1601.                )
  1602. returns OK if something exists, sets used and alloc to the total space
  1603. allocated to the object and all of it's subobjects in 1000's of bytes.
  1604.  
  1605.  
  1606. long cfstackdepth(
  1607.                   void *handle
  1608.                  )
  1609. returns the current stackdepth of the object or ERROR
  1610.  
  1611.  
  1612. long cfcurbufs(
  1613.                void
  1614.               )
  1615. returns the current allowed localizer buffer space in K bytes.
  1616.  
  1617.  
  1618. long cfisnew(
  1619.              void *handle
  1620.             )
  1621. returns 1 if object is newly created, 0 if not, ERROR if invalid handle
  1622.  
  1623.  
  1624. long cffilesize(
  1625.                 void *handle
  1626.                )
  1627. returns the size of the file property of the object or ERROR
  1628.  
  1629.  
  1630. long cffilealloc(
  1631.                  void *handle
  1632.                 )
  1633. returns the space allocated to the file property or ERROR
  1634.  
  1635.  
  1636. long cfprealloc(
  1637.                 void *handle
  1638.                )
  1639. returns the size of each preallocated chunk or 0 or ERROR
  1640.  
  1641.  
  1642. long cfmapsize(
  1643.                void *handle
  1644.               )
  1645. returns the node size of the object or ERROR
  1646.  
  1647.  
  1648. long cfalignment(
  1649.                  void *handle
  1650.                 )
  1651. returns the alignment for the object (32 is hardwired in version 5.1)
  1652.  
  1653.  
  1654. long cfissorted(
  1655.                 void *handle
  1656.                )
  1657. returns 1 if the object is sorted, 0 if not or ERROR
  1658.  
  1659.  
  1660. void cfprintbitmaps(
  1661.                     void *something  // a path or handle
  1662.                    )
  1663. Prints the bitmaps for the target object and it's parents.
  1664.  
  1665.  
  1666. void cfprintentries(
  1667.                     void *something  // a path or handle
  1668.                    )
  1669. Prints all the entries in the target object's nodes.
  1670.  
  1671. long cfhash(
  1672.             void *keyptr,
  1673.             int   keylen,
  1674.             CAT  *cat    // pointer to a CAT structure
  1675.            )
  1676. Calls the system hash function for the supplied key. The CAT structure
  1677. receives the hashed output. Useful for generating random numbers etc.
  1678. Returns OK.
  1679.    
  1680.  
  1681. long cfobtype(
  1682.               void *something
  1683.              )
  1684. returns the OB bits or ERROR
  1685.  
  1686. #define OB_SHARE    0x00000001  // object can be opened more than once
  1687. #define OB_ISDIR    0x00000002  // object is a directory
  1688. #define OB_BMOK     0x00000004  // bitmaps loaded
  1689. #define OB_SMOK     0x00000008  // storage maps loaded
  1690. #define OB_MEM      0x00000010  // memory object
  1691. #define OB_RAWDEV   0x00000020  // raw device
  1692. #define OB_CFILE    0x00000040  // part of a disk filesys
  1693. #define OB_SETUP    0x00000080  // object is setup
  1694. #define OB_FOD      0x00000100  // on a file oriented device
  1695. #define OB_ROOTDIR  0x00000200  // object is the root directory
  1696. #define OB_DIRTY    0x00000400  // has been written to
  1697. #define OB_DELCLOSE 0x00000800  // delete on close
  1698. #define OB_WRITE    0x00001000  // ok to write to this object
  1699. #define OB_BITMAP   0x00002000  // has a bitmap
  1700. #define OB_XFILE    0x00004000  // is an external OS file
  1701. #define OB_ISNEW    0x00008000  // newly created
  1702. #define OB_SMEM     0x00010000  // extended memory object
  1703. #define OB_FILEONLY 0x40000000  // created with F_FILEONLY
  1704. #define OB_HASHDIR  0x20000000  // uses hashed maps
  1705. #define OB_TREEDIR  0x10000000  // uses B+ tree maps
  1706. #define OB_UNTAGGED 0x08000000  // contains untagged items
  1707. #define OB_PREALLOC 0x01000000  // contains prealloced data and entries
  1708.  
  1709.  
  1710.  
  1711.